package com.hainingtong.busapi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hainingtong.busapi.bean.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BusApi extends BusRequest {

    final private static String baseUrl = "https://dyy.xiaobu.hk/city-api/bus/";

    /**
     * 查看最新的路况通知信息
     *
     * @return map
     */
    public static List<Notice> noticeLatestList() {
        String result = request("notice/latest/list");

        Result<NoticeResult> ret = JSONObject.parseObject(result, new TypeReference<Result<NoticeResult>>() {
        });

        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody().getList();
    }

    /**
     * 查看路况通知
     *
     * @return map
     */
    public static List<Notice> noticeList() {
        return noticeList(1);
    }

    /**
     * 查看路况通知
     *
     * @param page 分页
     * @return map
     */
    public static List<Notice> noticeList(int page) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("PAGE_INDEX", 1);
        jsonObj.put("PAGE_CAPACITY", 20);
        String result = request("notice/list", jsonObj);
        Result<NoticeResult> ret = JSONObject.parseObject(result, new TypeReference<Result<NoticeResult>>() {
        });

        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody().getList();
    }

    public static Schedule routeTodaySchedule(int busId) {
        return routeTodaySchedule(busId, 1);
    }

    /**
     * 查看指定公交当天的时刻表
     *
     * @param busId     公交编号 对应 SUB_ROUTEID
     * @param direction 方向 1或2
     * @return map
     */
    public static Schedule routeTodaySchedule(int busId, int direction) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("SUB_ROUTEID", busId);
        jsonObj.put("BUS_DIRECTION", direction);
        Result<Schedule> ret = JSONObject.parseObject(request("route/today_schedule", jsonObj), new TypeReference<Result<Schedule>>() {
        });

        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }

    /**
     * 根据公交车id获取站牌列表信息，以及公交信息，默认查询方向
     *
     * @param busId 公交编号，对应 SUB_ROUTEID
     * @return 返回json解析后的map
     */
    public static StationResult busQueryBus(int busId) {
        return busQueryBus(busId, 1);
    }

    /**
     * 根据公交车id获取站牌列表信息，以及公交信息
     *
     * @param busId     公交编号
     * @param direction 方向，1或2
     * @return 返回json解析后的map
     */
    public static StationResult busQueryBus(int busId, int direction) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("SUB_ROUTEID", busId);
        jsonObj.put("BUS_DIRECTION", direction);
        Result<StationResult> ret = JSONObject.parseObject(request("bus/querybus", jsonObj), new TypeReference<Result<StationResult>>() {
        });

        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }

    /**
     * 线路时刻表
     *
     * @param busId     线路编号
     * @param direction 方向
     * @return map
     */
    public static ScheduleResult routeSchedules(int busId, int direction) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("SUB_ROUTEID", busId);
        jsonObj.put("BUS_DIRECTION", direction);

        Result<ScheduleResult> ret = JSONObject.parseObject(request("route/schedules", jsonObj), new TypeReference<Result<ScheduleResult>>() {
        });

        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }

    public static PlanRunTime busPlanRunTime(int busId, int direction) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("SUBROUTEID", busId);
        jsonObj.put("DIRECTION", direction);
        Result<PlanRunTime> ret = JSONObject.parseObject(request("bus/planRunTime", jsonObj), new TypeReference<Result<PlanRunTime>>() {
        });

        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }

    /**
     * 查看指定线路离指定站台有多少距离
     *
     * @param busId     公交编号
     * @param stationId 要查询的站台编号
     * @param direction 方向
     * @return
     */
    public static NowBus nowSameid3(String busId, String stationId, int direction) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("SUBROUTE_ID", busId);
        jsonObj.put("SAME_ID", stationId);
        jsonObj.put("TYPE", direction);
        Result<NowBus> ret = JSONObject.parseObject(request("now/sameid3", jsonObj), new TypeReference<Result<NowBus>>() {
        });
//        System.out.println(result);

        return ret.getBody();
    }


    public static SearchResult busSearch(String name) {
        return busSearch(name, 1, 5);
    }

    public static SearchResult busSearch(String name, int page) {
        return busSearch(name, page, 5);
    }

    /**
     * 根据名字查询线路和公交站列表
     *
     * @param name     公交线路名 或 站点名称
     * @param page     显示第几页
     * @param pageSize 每页几条数据
     * @return map 包含 线路 和 站点列表
     */
    public static SearchResult busSearch(String name, int page, int pageSize) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("IMPORT", name);
        jsonObj.put("PAGE_INDEX", page);
        jsonObj.put("PAGE_CAPACITY", pageSize);
        Result<SearchResult> ret = JSONObject.parseObject(request("import", jsonObj), new TypeReference<Result<SearchResult>>() {
        });
        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }

    public static BusInfoResult busWithDirectionByStation(String stationId) {
        return busWithDirectionByStation(stationId, 1, 10);
    }

    public static BusInfoResult busWithDirectionByStation(String stationId, int page) {
        return busWithDirectionByStation(stationId, page, 10);
    }

    /**
     * 根据站点编号查询同站路线
     *
     * @param stationId 线路编号
     * @param page      当前页
     * @param pageSize  每页大小
     * @return map
     */
    public static BusInfoResult busWithDirectionByStation(String stationId, int page, int pageSize) {
        HashMap<String, Object> jsonObj = new HashMap<>();
        jsonObj.put("IMPORT", stationId);
        jsonObj.put("PAGE_INDEX", page);
        jsonObj.put("PAGE_CAPACITY", pageSize);
        Result<BusInfoResult> ret = JSONObject.parseObject(request("busWithDirectionBystation", jsonObj), new TypeReference<Result<BusInfoResult>>() {
        });
        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }

    /**
     * 根据起始点经纬度查询线路
     *
     * @param startLongitude
     * @param startLatitude
     * @param endLongitude
     * @param endLatitude
     * @param queryNumber
     * @param lineType
     * @return BusInfoResult
     */
    public static BusInfoResult lineLatitudeLongitude(
            String startLongitude,
            String startLatitude,
            String endLongitude,
            String endLatitude,
            int queryNumber,
            int lineType
    ) {
        HashMap<String, Object> jsonObj = new HashMap<>();

        jsonObj.put("START_LONGITUDE", startLongitude);
        jsonObj.put("START_LATITUDE", startLatitude);
        jsonObj.put("END_LONGITUDE", endLongitude);
        jsonObj.put("END_LATITUDE", endLatitude);
        jsonObj.put("QUERY_NUMBER", queryNumber);
        jsonObj.put("LINE_TYPE", lineType);
        Result<BusInfoResult> ret = JSONObject.parseObject(request("line/latitudelongitude", jsonObj), new TypeReference<Result<BusInfoResult>>() {
        });
        // 返回错误信息，直接返回
        if (ret == null || !ret.getRspmsg().equals("succeed")) {
            return null;
        }

        return ret.getBody();
    }


    private static String request(String api) {
        return request(api, JSONObject.parseObject("{}"));
    }

    private static String request(String api, Map jsonObj) {
        String jsonStr = sign(JSON.toJSONString(jsonObj));
        System.out.println(jsonStr);
        String url = baseUrl + api + "?token=hnx";
        CloseableHttpClient httpClient = null;
        HttpPost postMethod = null;
        HttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            postMethod = new HttpPost(url);//传入URL地址
            //设置请求头
            postMethod.addHeader("Content-type", "application/json; charset=utf-8");
            postMethod.addHeader("X-Requested-With", "com.haining.busapp");
            postMethod.addHeader("Origin", "file://");
            postMethod.addHeader("CoreUser-Agent", "Mozilla/5.0 (Linux; Android 5.1.1; TAS-AN00 Build/TAS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 xiaobuwebview(dyy/1.3.0/1.0.0)");
            //传入请求参数
            postMethod.setEntity(new StringEntity(jsonStr, StandardCharsets.UTF_8));
            response = httpClient.execute(postMethod);//获取响应
            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("HTTP Status Code:" + statusCode);
            if (statusCode != HttpStatus.SC_OK) {
                System.out.println("HTTP请求未成功！HTTP Status Code:" + response.getStatusLine());
            }
            HttpEntity httpEntity = response.getEntity();
            String reponseContent = EntityUtils.toString(httpEntity);
            EntityUtils.consume(httpEntity); //释放资源
            System.out.println("响应内容：" + reponseContent);
            return reponseContent;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
